﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Web.UI;
using TA.JSON;
using System.IO;
using System.Web.UI.HtmlControls;
using System.Web.UI.Design;
using System.ComponentModel.Design;
using System.Drawing.Design;
using TA.Turbo.Design;


namespace TA.Turbo.Controls
{
	/// <summary>
	/// Tab container which renders a number of tab panels and allows switching between them.
	/// </summary>
	[ParseChildren(true)]
	[Designer(typeof(ContainerControlDesigner))]
	public class TabContainer : BaseComplexControl
	{
		#region PUBLIC
		#region INIT
		/// <summary>
		/// Ctor.
		/// </summary>
		public TabContainer()
		{
			_panels = new TabPanelCollection(this);
			Tag = System.Web.UI.HtmlTextWriterTag.Div;

			_divHeader.Attributes["class"] = "header";
			this.Controls.Add(_divHeader);
			_divMain.Attributes["class"] = "body";
			this.Controls.Add(_divMain);
		}
		#endregion
		#region PROPS
		#region DEF
		/// <summary>
		/// Props.
		/// </summary>
		protected static new Properties _clientProperties = Define(BaseComplexControl._clientProperties,
			new BasePropertyDefinition[] {
				new PropertyDefinition<int>("ActiveTabIndex", "AT", 0),
				new NullablePropertyDefinition<int>("Height", "H", null),
			});
		/// <summary>
		/// Props.
		/// </summary>
		public override Properties ClientProperties
		{
			get
			{
				return _clientProperties;
			}
		}
		#endregion
		/// <summary>
		/// Gets the collection of tab panels.
		/// </summary>
		[PersistenceMode(PersistenceMode.InnerProperty)]
		public ControlCollection<TabPanel> Panels { get { return this._panels; } }
		/// <summary>
		/// Gets or sets the currently active tab.
		/// </summary>
		[Browsable(false)]
		public TabPanel ActiveTab
		{
			get
			{
				return Panels[ActiveTabIndex];
			}
			set
			{
				ActiveTabIndex = Panels.IndexOf(value);
			}
		}
		/// <summary>
		/// Gets or sets the index of the currently active tab.
		/// </summary>
		[DefaultValue(0)]
		public int ActiveTabIndex
		{
			get
			{
				return GetProperty<int>("ActiveTabIndex");
			}
			set
			{
				if (value < 0 || value >= this.Panels.Count)
					throw new ArgumentOutOfRangeException("value");

				ViewState["ActiveTabIndex"] = value;

				this.VerifyActiveTab();
			}
		}
		/// <summary>
		/// Gets or sets the height of all tab panels, in pixels.
		/// </summary>
		[DefaultValue(null)]
		public int? Height
		{
			get
			{
				return this.GetProperty<int?>("Height");
			}
			set
			{
				this.ViewState["Height"] = value;
			}
		}
		#endregion
		#region EVENTS
		[PersistenceMode(PersistenceMode.InnerProperty)]
		[NotifyParentProperty(true)]
		//[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
		public ServerEvent<EventArgs> ActiveTabIndexChanging
		{
			get
			{
				return this.GetServerEvent<EventArgs>("ActiveTabIndexChanging");
			}
		}
		[PersistenceMode(PersistenceMode.InnerProperty)]
		[NotifyParentProperty(true)]
		//[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
		public ServerEvent<EventArgs> ActiveTabIndexChanged
		{
			get
			{
				return this.GetServerEvent<EventArgs>("ActiveTabIndexChanged");
			}
		}
		#endregion
		#endregion
		#region INTERNAL
		#region METHODS
		/// <summary>
		/// Registers TabContainer.js.
		/// </summary>
		protected internal override void RegisterIncludes(IncludeCollection includes)
		{
			base.RegisterIncludes(includes);

			includes.Add(Script.ElementSearch);
			includes.Add(new ScriptResourceInclude("TA.Turbo.Res.JS.TabContainer.js", typeof(TabContainer)));
		}

		internal void AddPanel(TabPanel p)
		{
			p._container = this;
			_divMain.Controls.Add(p);

		}
		/// <summary>
		/// Verifies that the active tab panel is enabled and if not, tries adjusting the active tab index to the nearest enabled tab panel.
		/// </summary>
		protected internal void VerifyActiveTab()
		{
			int ti = this.ActiveTabIndex;
			if (!this.Panels[ti].Shown)
			{
				for (int i = 1; i <= Math.Max(ti, this.Panels.Count - ti); ++i)
				{
					int testing = ti + i;
					if (testing < Panels.Count)
					{
						if (this.Panels[testing].Enabled)
						{
							this.ActiveTabIndex = testing;
							break;
						}
					}
					testing = ti - i;
					if (testing >= 0)
					{
						if (this.Panels[testing].Enabled)
						{
							this.ActiveTabIndex = testing;
							break;
						}
					}
				}
			}
		}
		/// <summary>
		/// Renders the children tab panels.
		/// </summary>
		/// <param name="writer"></param>
		protected override void RenderChildren(HtmlTextWriter writer)
		{
			for (int i = 0; i < this.Panels.Count; ++i)
			{
				Panels[i]._spanTab.Attributes["class"] =
					Panels[i].CssClass =
					ActiveTabIndex == i ? "active" : "";

				this.Panels[i].Shown = this.ActiveTabIndex == i;
				//Panels[i].Style[HtmlTextWriterStyle.Display] = ActiveTabIndex == i ? "" : "none";
			}

			base.RenderChildren(writer);
		}
		#endregion
		#region VARS
		ControlCollection<TabPanel> _panels;
		internal HtmlGenericControl _divHeader = new HtmlGenericControl("div"),
			_divMain = new HtmlGenericControl("div");
		#endregion
		#endregion
	}
}
